package com.koron.order.common.controller;


import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.koron.bean.base.Response;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.order.common.bean.vo.OrderExecuteVo;
import com.koron.order.common.service.OrderExecuteInfoService;
import com.koron.order.defect.bean.vo.DefectExecuteVO;
import com.koron.order.defect.service.ExecuteService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.IntStream;

/**
 * @ClassName OrderExecuteController
 * @description
 * @Author zhouj
 * @Date 2021/9/23 17:40
 */
@Api(tags = "工单执行")
@RequestMapping("/orderExecute/")
@RestController
public class OrderExecuteController {

    public String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    @Autowired
    OrderExecuteInfoService orderExecuteInfoService;

    @Autowired
    private ExecuteService executeService;

    @ApiOperation(value = "orderId查询执行信息列表")
    @GetMapping("queryExecuteInfoByOrderId")
    public Response<List<OrderExecuteVo>> queryExecuteInfoByOrderId(String orderId) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), orderExecuteInfoService, "queryListByOrderId", List.class, orderId));
    }

    @ApiOperation(value = "executeId查询执行信息")
    @GetMapping("queryExecuteInfoByExecuteId")
    public Response<OrderExecuteVo> querySingleByExecuteId(String executeId) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), orderExecuteInfoService, "querySingleByExecuteId", OrderExecuteVo.class, executeId));
    }

    @ApiIgnore
    @ApiOperation(value = "新增或修改工单执行信息")
    @PostMapping("saveExecuteInfo")
    public Response<String> insertOrUpdateExecuteInfo(@RequestBody OrderExecuteVo orderExecuteVo) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), orderExecuteInfoService, "insertOrUpdateExecuteInfo", String.class, orderExecuteVo));
    }

    @ApiOperation(value = "orderId查询可提交人员列表")
    @GetMapping("querySubmitUserListByOrderId")
    public Response<List> querySubmitUserListByOrderId(@RequestParam(value = "orderId", required = true) String orderId,
                                                    @RequestParam(value = "isLeader", required = false, defaultValue = "false") Boolean isLeader) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), orderExecuteInfoService, "querySubmitUserListByOrderId", List.class, orderId, isLeader));
    }

    @ApiOperation(value = "删除执行信息")
    @DeleteMapping("deleteExecuteInfoByExecuteId")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderExecuteId", value = "工单执行Id", required = false, dataType = "String"),
            @ApiImplicitParam(name = "orderId", value = "工单Id", required = false, dataType = "String")
    })
    public Response<Boolean> deleteExecuteInfoByExecuteId(@RequestParam(value = "orderExecuteId", required = false) String orderExecuteId,
                                                          @RequestParam(value = "orderId", required = false) String orderId) {
        Assert.hasText(orderId + orderExecuteId);
        return Response.ok(ADOConnection.runTask(getCurrDs(), orderExecuteInfoService, "deleteExecuteInfo", Boolean.class, orderId, orderExecuteId));
    }

    @ApiOperation(value = "备件信息补录")
    @PostMapping("recodePart")
    public Response<Boolean> recodeSparePart(@RequestBody List<DefectExecuteVO> defectExecuteVOList){
        Boolean result = ADOConnection.runTask(getCurrDs(), orderExecuteInfoService, "recodePart", Boolean.class, defectExecuteVOList);
        return Response.ok(result);
    }

    @ApiOperation(value = "导出执行信息")
    @GetMapping("exportExecuteInfo")
    public void exportExecuteInfo(String orderId, HttpServletResponse resp) throws IOException {
        List<DefectExecuteVO> list = ADOConnection.runTask(getCurrDs(), executeService, "queryListByOrderId", List.class, orderId);
        List<Map<String,Object>> rows = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)){
            return;
        }
        for (DefectExecuteVO orderExecuteVo : list) {
                Map<String,Object> row = new LinkedHashMap<>();
                row.put("设备名称",orderExecuteVo.getEquipmentName());
                row.put("专业",convertMajor(orderExecuteVo.getMajorId()));
                row.put("缺陷是否描述准确",orderExecuteVo.getTrueStatus() == 1 ? "准确" : "不准确");
                row.put("缺陷原因类型",convertReasonType(orderExecuteVo.getReasonType()));
                row.put("缺陷原因",orderExecuteVo.getReason());
                row.put("实际开始时间",orderExecuteVo.getFactStartTime());
                row.put("实际结束时间",orderExecuteVo.getFactEndTime());
                row.put("维护内容",orderExecuteVo.getRemainDesc());
                row.put("是否遗留问题",orderExecuteVo.getRemainStatus() == 1 ? "是":"否");
                row.put("是否可投入使用",orderExecuteVo.getRunStatus() == 1 ? "可投入使用":"不可投入使用");
                rows.add(row);
        }
        ExcelWriter writer = ExcelUtil.getWriter(true);

        writer.merge(9,"执行信息");
        writer.write(rows,true);
        writer.setColumnWidth(0,16);
        writer.setColumnWidth(2,16);
        writer.setColumnWidth(3,16);
        writer.setColumnWidth(4,22);
        writer.setColumnWidth(5,22);
        writer.setColumnWidth(6,22);

        String fileName = URLEncoder.encode("执行信息", "UTF-8").replaceAll("\\+", "%20");
        // 此处的response.setContentType 和教程里的不同
        resp.setContentType("application/octet-stream");
        // filename就是表格的名字，这个无所谓，反正前端还会重命名
        resp.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
        // 输出流
        ServletOutputStream servletOutputStream = resp.getOutputStream();
        writer.flush(servletOutputStream,true);
        // 关闭writer，释放内存
        writer.close();
        // 关闭输出Servlet流
        IoUtil.close(servletOutputStream);

    }

    // 筛选出缺陷原因类型
    private String convertReasonType(String reasonType) {
        List<String> reasonTypes = Arrays.asList("design_quality","product_quality","operation_maintenance_quality","construct_quality","acceptance_quality","equipment_worn_out","external_influence","other");
        List<String> reasonTypeNames = Arrays.asList("设计质量","产品质量","运维质量","施工质量","验收质量","设备老化","外部影响","其它");
        Map<String, String> map = IntStream.range(0, reasonTypes.size())
                .collect(HashMap::new, (m, j) -> m.put(reasonTypes.get(j), reasonTypeNames.get(j)), (m, n) -> { });
        return map.get(reasonType);
    }

    // 筛选出专业
    private String convertMajor(String majorId) {

        List<String> majors = Arrays.asList("machine","electric","automate","communication","synthesis","others");
        List<String> majorNames = Arrays.asList("机械","电气","自动化","通讯","综合","其他");
        Map<String, String> map = IntStream.range(0, majors.size())
                .collect(HashMap::new, (m, j) -> m.put(majors.get(j), majorNames.get(j)), (m, n) -> { });

        return map.get(majorId);
    }
}

